package com.example.origin.demo.demo;

import lombok.SneakyThrows;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;

@RequestMapping("TryLockDemo")
@RestController
public class TryLockDemo {


    @SneakyThrows
    @GetMapping("test")
    public void test() {
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+":start");
            lock(e->{
                try {
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println(Thread.currentThread().getName()+":stop");
                } catch (InterruptedException ex) {
                    throw new RuntimeException(ex);
                }
            });
        }).start();
        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+":start");
            lock(e->{
                try {
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println(Thread.currentThread().getName()+":stop");
                } catch (InterruptedException ex) {
                    throw new RuntimeException(ex);
                }
            });
        }).start();

        TimeUnit.SECONDS.sleep(20);
    }

    ReentrantLock reentrantLock = new ReentrantLock();
    @SneakyThrows
    private void lock(Consumer consumer) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        try {
            if (reentrantLock.tryLock(3, TimeUnit.SECONDS)) {
                consumer.accept(null);
                reentrantLock.unlock();
            }
        }finally {
            stopWatch.stop();
            System.out.println(Thread.currentThread().getName()+":"+stopWatch.getTotalTimeMillis());
        }

    }

}
